#ifndef __EXCEPTION_MACRO_H__
#define __EXCEPTION_MACRO_H__

#include "Exception.h"
#include "dumpcrash.h"
#include "DumpFuncAddress.h"

#define DUMP_FUNC_BUF_LEN 2048
#define DUMP_LEVEL  10

#define SEH_TRY                 SBASE_TRY{
#define SEH_CATCH(message)      } SBASE_CATCH_DUMP(#message);

#ifdef _DEBUG
#define		SBASE_TRY		{
#else
#define		SBASE_TRY		try{
#endif // _DEBUG


#define		SBASE_CATCH_EX(s, dump)			}\
catch(sbase::IException& ex) \
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	DWORD dwCode = 0; if(ex.GetExceptionInfo()&& ex.GetExceptionInfo()->ExceptionRecord) dwCode=ex.GetExceptionInfo()->ExceptionRecord->ExceptionCode;\
	if(dump) \
	{ \
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
		DumpException(ex.GetExceptionInfo()); \
	}\
	else\
	{\
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	}\
}\
catch(std::exception& ex)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, ex.what(), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, ex.what(), szBuf); \
	}\
}\
catch(...)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, szBuf); \
	}\
}\


#ifdef _DEBUG
#define		SBASE_CATCH_DUMP(s)			}
#else
#define		SBASE_CATCH_DUMP(s)		SBASE_CATCH_EX(s, true)	
#endif // _DEBUG


#define		SBASE_CATCH2_EX(s, x, dump)			}\
catch(sbase::IException& ex) \\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	DWORD dwCode = 0; if(ex.GetExceptionInfo()&& ex.GetExceptionInfo()->ExceptionRecord) dwCode=ex.GetExceptionInfo()->ExceptionRecord->ExceptionCode;\
	if(dump) \
	{ \
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
		DumpException(ex.GetExceptionInfo()); \
	}\
	else\
	{\
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	}\
}\
catch(std::exception& ex)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x), ex.what(), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x), ex.what(), szBuf); \
	}\
}\
catch(...)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), szBuf); \
	}\
}\

#ifdef _DEBUG
#define		SBASE_CATCH2_DUMP(s, x)			}
#else
#define		SBASE_CATCH2_DUMP(s, x)		SBASE_CATCH2_EX(s,x, true)	
#endif // _DEBUG



#define		SBASE_CATCH3_EX(s, x, y, dump)			}\
	catch(sbase::IException& ex) \
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	DWORD dwCode = 0; if(ex.GetExceptionInfo()&& ex.GetExceptionInfo()->ExceptionRecord) dwCode=ex.GetExceptionInfo()->ExceptionRecord->ExceptionCode;\
	if(dump) \
	{ \
	LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	DumpException(ex.GetExceptionInfo()); \
	}\
	else\
	{\
	LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y),sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	}\
}\
	catch(std::exception& ex)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x),(y), ex.what(), szBuf); \
	DumpException(); \
	}\
	else\
	{\
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x), (y),ex.what(), szBuf); \
	}\
}\
	catch(...)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y),szBuf); \
	DumpException(); \
	}\
	else\
	{\
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y),szBuf); \
	}\
}\

#ifdef _DEBUG
#define		SBASE_CATCH3_DUMP(s, x, y)			}
#else
#define		SBASE_CATCH3_DUMP(s, x, y)		SBASE_CATCH3_EX(s,x, y, true)	
#endif // _DEBUG



#define		SBASE_CATCH4_EX(s, x, y, z, dump)			}\
catch(sbase::IException& ex) \
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	DWORD dwCode = 0; if(ex.GetExceptionInfo()&& ex.GetExceptionInfo()->ExceptionRecord) dwCode=ex.GetExceptionInfo()->ExceptionRecord->ExceptionCode;\
	if(dump) \
	{ \
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y), (z), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
		DumpException(ex.GetExceptionInfo()); \
	}\
	else\
	{\
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y), (z), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	}\
}\
catch(std::exception& ex)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x),(y),  (z), ex.what(), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x), (y),  (z), ex.what(), szBuf); \
	}\
}\
catch(...)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y), (z), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y),  (z), szBuf); \
	}\
}\


#ifdef _DEBUG
#define		SBASE_CATCH4_DUMP(s,x,y,z)	}
#else
#define		SBASE_CATCH4_DUMP(s,x,y,z)	SBASE_CATCH4_EX(s,x,y,z,true)
#endif // _DEBUG


#define		SBASE_CATCH3_EX(s, x, y, dump)			}\
	catch(sbase::IException& ex) \
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	DWORD dwCode = 0; if(ex.GetExceptionInfo()&& ex.GetExceptionInfo()->ExceptionRecord) dwCode=ex.GetExceptionInfo()->ExceptionRecord->ExceptionCode;\
	if(dump) \
	{ \
	LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	DumpException(ex.GetExceptionInfo()); \
	}\
	else\
	{\
	LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y),sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	}\
}\
	catch(std::exception& ex)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x),(y), ex.what(), szBuf); \
	DumpException(); \
	}\
	else\
	{\
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x), (y),ex.what(), szBuf); \
	}\
}\
	catch(...)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y),szBuf); \
	DumpException(); \
	}\
	else\
	{\
	sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
	LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y),szBuf); \
	}\
}\


#ifdef _DEBUG
#define		SBASE_CATCH3_DUMP(s, x, y)			}
#else
#define		SBASE_CATCH3_DUMP(s, x, y)		SBASE_CATCH3_EX(s,x, y, true)	
#endif // _DEBUG



#define		SBASE_CATCH5_EX(s, x, y, z, h,dump)			}\
catch(sbase::IException& ex) \
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	DWORD dwCode = 0; if(ex.GetExceptionInfo()&& ex.GetExceptionInfo()->ExceptionRecord) dwCode=ex.GetExceptionInfo()->ExceptionRecord->ExceptionCode;\
	if(dump) \
	{ \
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y), (z), (h), sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
		DumpException(ex.GetExceptionInfo()); \
	}\
	else\
	{\
		LOGEXPT("CATCH(sbase::IException& ex): *** %s %d {" s "} crash! ***\n%s(%s)", __FILE__, __LINE__, (x), (y), (z), (h),  sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1, ex.GetExceptionInfo()) , ex.GetName()); \
	}\
}\
catch(std::exception& ex)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x),(y),  (z),  (h), ex.what(), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(std::excetion): *** %s %d {" s "} crash! Exception[%s] %s\n***\r\n", __FILE__, __LINE__, (x), (y),  (z),  (h), ex.what(), szBuf); \
	}\
}\
catch(...)\
{ \
	char szBuf[DUMP_FUNC_BUF_LEN] = {0x00}; \
	if(dump) \
	{ \
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y), (z),  (h), szBuf); \
		DumpException(); \
	}\
	else\
	{\
		sbase::DumpFuncAddress(DUMP_LEVEL, szBuf, DUMP_FUNC_BUF_LEN - 1);\
		LOGEXPT("CATCH(...): *** %s %d {" s "} crash! %s\n***\r\n", __FILE__, __LINE__, (x), (y),  (z),  (h), szBuf); \
	}\
}\

#ifdef _DEBUG
#define		SBASE_CATCH5_DUMP(s,x,y,z,h)	}
#else
#define		SBASE_CATCH5_DUMP(s,x,y,z,h)		SBASE_CATCH5_EX(s,x,y,z,h,true)	
#endif // _DEBUG





#endif